<?php

require_once(BaseConfig::LoadClass('conecta.class.php'));

/**
 * Clase que maneja las operaciones de Agregar, Actualizar y Borrar de los catálogos.
 */
class OperacionesDB {

  /**
   * Crea una cadena de INSERT para ser insertada en la base de datos
   *
   * @param String $strTabla   Tabla a la que se le hará la inserción
   * @param Array  $arrNombres Arreglo con los nombres de las columnas
   * @param Array  $arrTipos   Arreglo con los tipos de cada columna
   * @param Array  $arrValores Arreglo con los valores de cada columna
   *
   * @see  OperacionesDB::__ArrayIUPrepare
   * @uses OperacionesDB::__ArrayIUPrepare
   *
   * @return String Query para ser ejecutado por Conecta
   */
  static function CrearInsert($strTabla, $arrNombres, $arrTipos = "", $arrValores = "") {
    $arrValoresPreparados = OperacionesDB::__ArrayIUPrepare($arrNombres, $arrTipos, $arrValores);

    $strInsercionColumnas = $strInsercionValores = '';
    foreach($arrValoresPreparados['Nombres'] as $strNombreColumna) {
      if($arrValoresPreparados['Tipos'][$strNombreColumna] == 'I') continue; // No se inserta la columna de indice automático

      switch($arrValoresPreparados['Tipos'][$strNombreColumna]) {
        case 'I': case 'N':
          $strValorColumna = $arrValoresPreparados['Valores'][$strNombreColumna] - 0;
          break;
        case 'D':
/*
          $intMarcaTiempo = strtotime($arrValoresPreparados['Valores'][$strNombreColumna]);
          if(($intMarcaTiempo === false) || ($intMarcaTiempo === -1)) {
            $strValorColumna = "'0000-00-00 00:00:00'";
          } else {
            $strValorColumna = "'" . date("Y-m-d H:i:s", $intMarcaTiempo) . "'";
          }
// */     $strValorColumna = "'" . $arrValoresPreparados['Valores'][$strNombreColumna] . "'";
          break;
        case 'S': default:
          $strValorColumna = "'" . OperacionesDB::CambioValoresNoPosiblesDB($arrValoresPreparados['Valores'][$strNombreColumna]) . "'";
          break;
      }

      $strInsercionColumnas .= $strNombreColumna . ', ';
      $strInsercionValores  .= $strValorColumna  . ', ';
    }
    
    $strInsercionColumnas = substr($strInsercionColumnas, 0, -2);
    $strInsercionValores  = substr($strInsercionValores , 0, -2);

    $strConsulta = "INSERT INTO $strTabla ($strInsercionColumnas) VALUES ($strInsercionValores)";

    return $strConsulta;
  }

  /**
   * Crea una cadena de UPDATE para ser insertada en la base de datos
   *
   * @param String $strTabla   Tabla a la que se le hará la actualización
   * @param Array  $arrNombres Arreglo con los nombres de las columnas
   * @param Array  $arrTipos   Arreglo con los tipos de cada columna
   * @param Array  $arrValores Arreglo con los valores de cada columna
   *
   * @see  OperacionesDB::__ArrayIUPrepare
   * @uses OperacionesDB::__ArrayIUPrepare
   *
   * @return String Query para ser ejecutado por Conecta
   */
  static function CrearUpdate($strTabla, $arrNombres, $arrTipos = "", $arrValores = "") {
    $arrValoresPreparados = OperacionesDB::__ArrayIUPrepare($arrNombres, $arrTipos, $arrValores);
    $strNombreIndice = ''; // El nombre del indice en la tabla

    $strConsulta = 'UPDATE ' . $strTabla . ' SET ';
    foreach($arrValoresPreparados['Nombres'] as $strNombreColumna) {
      if(($arrValoresPreparados['Tipos'][$strNombreColumna] == 'I') || ($arrValoresPreparados['Tipos'][$strNombreColumna] == 'IS')) {
        $strNombreIndice = $strNombreColumna;
        continue; // No se inserta la columna de indice automático
      }

      $strConsulta .= $strNombreColumna . ' = ';

      switch($arrValoresPreparados['Tipos'][$strNombreColumna]) {
        case 'I': case 'N':
          $strConsulta .= $arrValoresPreparados['Valores'][$strNombreColumna] - 0;
          break;
        case 'D':
          $intMarcaTiempo = strtotime($arrValoresPreparados['Valores'][$strNombreColumna]);
          if(($intMarcaTiempo === false) || ($intMarcaTiempo === -1)) {
            $strConsulta .= "'0000-00-00 00:00:00'";
          } else {
            $strConsulta .= "'" . date("Y-m-d H:i:s", $intMarcaTiempo) . "'";
          }
          break;
        case 'S': case 'IS': default:
          $strConsulta .= "'" . OperacionesDB::CambioValoresNoPosiblesDB($arrValoresPreparados['Valores'][$strNombreColumna]) . "'";
          break;
      }

      $strConsulta .= ', ';
    }

    $strConsulta  = substr($strConsulta, 0, -2);
    if($arrValoresPreparados['Tipos'][$strNombreIndice] == 'IS') {
      $strConsulta .= ' WHERE ' . $arrValoresPreparados['Nombres'][$strNombreIndice] . ' = \'' . $arrValoresPreparados['Valores'][$strNombreIndice] . '\'';
    } else {
      $strConsulta .= ' WHERE ' . $arrValoresPreparados['Nombres'][$strNombreIndice] . ' = ' . ($arrValoresPreparados['Valores'][$strNombreIndice] - 0);
    }

    return $strConsulta;
  }

  /**
   * Crea una cadena de INSERT para ser insertada en la base de datos
   *
   * Si los arreglos son pasados, llevarán la llave como el nombre de la columna, como en
   *
   * $arrNombres['nombre'] = 'nombre';
   *
   * $arrTipos  ['nombre'] = 'S'     ;
   * 
   * $arrValores['nombre'] = 'LuGiA' ;
   *
   * Si el arreglo $arrValores no es pasado, $arrNombres será tomado como que la llave es el nombre y el valor es el valor.
   * Si $arrTipos no es pasado, se tomará como que la primer llave es el indice y todas las demas son cadenas
   *
   * @param Array $arrNombres Arreglo con los nombres de las columnas
   * @param Array $arrTipos   Arreglo con los tipos de cada columna ('S' para String, 'N' para numero, 'I' para el indice autoincrementable)
   * @param Array $arrValores Arreglo con los valores de cada columna
   *
   * @return Array('Nombres','Tipos','Valores') Arreglo con los valores puestos para usarse
   */
  static function __ArrayIUPrepare($arrNombres, $arrTipos = "", $arrValores = "") {
    if(!is_array($arrTipos)) {
      unset($arrTipos);
      $arrTipos = Array();
      $i = 0;
      foreach($arrNombres as $strLlave => $strDummyVal) {
        if(!$i) {
          $i++;
          $arrTipos[$strLlave] = 'I';
        } else {
          $arrTipos[$strLlave] = 'S';
        }
      }
    }

    if(!is_array($arrValores)) {
      $arrNombresTmp = $arrNombres;
      unset($arrNombres);
      unset($arrValores);
      $arrNombres = Array();
      $arrValores = Array();
      foreach($arrNombresTmp as $strLlave => $strValor) {
        $arrNombres[$strLlave] = $strLlave;
        $arrValores[$strLlave] = $strValor;
      }
    }

    return Array('Nombres' => $arrNombres, 'Tipos' => $arrTipos, 'Valores' => $arrValores);
  }

  /**
   * Cambia los valores que no son posibles de insertar en la base de datos por los que si son posibles.
   *
   * Por el momento solo cambia la comilla simple (') por comilla doble (")
   *
   * @param String $strCadena La cadena a la que se le cambiarán los caracteres extraños
   *
   * @return String Cadena con los caracteres extraños cambiados
   */
  static function CambioValoresNoPosiblesDB($strCadena) {
    $strRet = str_replace("\\", "\\\\", $strCadena);
    $strRet = str_replace("'" , "\\'" , $strRet   );
    
    return $strRet;
  }

  /**
   * Función que checa si existen elementos en una tabla que cumplan con alguna caracteristica.
   *
   * @param String $strTabla Tabla en la que se checará el elemento
   * @param String $strWhere Caracteristica que necesitan cumplir los elementos (Parte de un "WHERE")
   *
   * @return int número de elementos que existen en la tabla.
   */
  static function ChecarExistenciaElementoPorId($strTabla, $strWhere) {
    $oConecta    = new Conecta();
    $strConsulta = "SELECT COUNT(*) AS cuantos FROM $strTabla ";
    if($strWhere) {
      $strConsulta .= "WHERE $strWhere";
    }
    $oConecta->Consulta($strConsulta);
    if($oConecta->EOF) {
      return 0;
    }
    return $oConecta->arrResultado["cuantos"] - 0;
  }
}

?>
